/*********************************************************************************
 *      Copyright:  (C) 2014 east
 *                  All rights reserved.
 *
 *       Filename:  server.c
 *    Description:  This file 
 *                 
 *        Version:  1.0.0(2014年10月11日)
 *         Author:  fulinux <fulinux@sina.com>
 *      ChangeLog:  1, Release initial version on "2014年10月11日 08时48分56秒"
 *                 
 ********************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/un.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <sys/time.h>

#define MAX_RECV 1025
#define UNIX_SERV_PATH "/tmp/sinfor"

void client_dump(int sock_fd)
{
    int ret;
    int size;
    int running = 1;
    fd_set rfds;
    char rec[MAX_RECV] = {0};
    struct timeval timeout;

    for(;running;){
        FD_ZERO(&rfds);
        FD_SET(sock_fd, &rfds);

        timeout.tv_sec = 3;
        timeout.tv_usec = 0;
        ret = select(sock_fd + 1, &rfds, NULL, NULL, &timeout);
        if(ret > 0){
            if((size = read(sock_fd, rec, MAX_RECV)) != 0){
                printf ("=========recv========\n");
                printf ("size = %d\n", size);
                printf ("recv data is %s\n", rec);
                write(sock_fd, rec, size);
            }else{
                printf ("size = %d\n", size);
                running = 0;
            }
        }else{
            printf ("timeout\n");
        }
    }
}

void sig_son(int num)
{
    printf ("son is %d\n", getpid());
    exit(0);
    wait(NULL);
}

int main (int argc, char **argv)
{
    int acc_sock, dump_sock;
    acc_sock = socket(AF_LOCAL, SOCK_SEQPACKET, 0);
    if(acc_sock == -1)
    {
        perror("socket func fail");
        return -1;
    }

    struct sockaddr_un ser_addr, cli_addr;
    ser_addr.sun_family = AF_LOCAL;
    strcpy(ser_addr.sun_path, UNIX_SERV_PATH);
    unlink(UNIX_SERV_PATH);
    bind(acc_sock, (struct sockaddr *)&ser_addr, sizeof(ser_addr));
    listen(acc_sock, 5);
    signal(SIGCHLD, sig_son);

    for(;;){
        socklen_t len = sizeof(cli_addr);
        dump_sock = accept(acc_sock, (struct sockaddr *)&cli_addr, &len);
        if(dump_sock == -1){
            if(errno == EINTR){
                continue;
            }else{
                perror("accept fail");
                return -1;
            }
        }

        if(fork() == 0){
            close(acc_sock);
            client_dump(dump_sock);
            close(dump_sock);
            exit(0);
        }

        close(dump_sock);
    }

    close(acc_sock);

    return 0;
} /* ----- End of main() ----- */

